# NOTE:
# *
# * THIS IMPLEMENTATION IS REWRITTEN FROM http://pastie.org/1927076
# *
# sidenote: doesn't seem to work properly...

# EDIT: I'm trying to change this algorithm in order to achieve something slightly different from the original goal...
# EIT@: Ok, let's just say it didn't work out either...

import random

MAXRAND = 127

def scrand(r = MAXRAND):
    return  (random.randint(0, 1000) % (2 * r))

rv = 0

def addNoise(value, r = MAXRAND):
    rv = scrand(r)

    if (value + rv) > MAXRAND:
        value = MAXRAND
    elif (value + rv) < -MAXRAND:
        value = -MAXRAND
    else:
        value = value + rv

    return value

def mdp(base, base_n, r):
    n = int((2 * base_n) - 1)

    map = [[-1 for i in range(n)] for j in range(n)]

    # resize
    i = 0
    j = 0
    while i < n:
        j = i%2
        
        while j < n:
            map[i][j] = base[i/2][j/2]
            j = j + 2
        i = i + 2
        
    # now I want to make a map that would contain values fron 0 to (n/2)
    
    i = 0
    j = 0
    
    while i < (n/2):
        j = 0
        
        while j < (n/2):
            map[2 * i][2 * j] = base[i][j]
            j = j + 1
        i = i + 1

    # Diamond algorithm
    # 0 0 0
    # 0 X 0
    # 0 0 0

    i = j = 1
    mapIJ = a = b = c = d = rv = 0
    
    while i < n:
        
        while j < n:
            mapIJ = map[i][j]
            a = map[i - 1][j - 1]
            b = map[i - 1][j + 1]
            c = map[i + 1][j - 1]
            d = map[i + 1][j + 1]
            mapIJ = (a + b + c + d)/4

#            mapIJ = addNoise(mapIJ, r)
                
            map[i][j] = mapIJ

            j = j + 2

        i = i + 2


    # Square algorithm
    # 0 1 0
    # 1 0 1
    # 0 1 0

    i = 0
    j = 0
    
    while i < n:
        j = ((i%2) + 1)%2
        
        while j < n:
            mapIJ = map[i][j]

            # get surrounding values
            a = b = c = d = 0

            if i != 0:
                a = int(map[i - 1][j])
            
            if j != 0:
                b = int(map[i][j - 1])

            if (j + 1) != n:
                c = int(map[i][j + 1])

            if (i + 1) != n:
                d = int(map[i + 1][j])
            
            # average calculation

            if i == 0:
                mapIJ = (b + c + d)/3

            elif j == 0:
                mapIJ = (a + c + d)/3

            elif (j + 1) == n:
                mapIJ = (a + b + d)/3

            elif (i + 1) == n:
                mapIJ = (a + b + c)/3

            else:
                mapIJ = (a + b + c + d)/4

#            mapIJ = addNoise(mapIJ, r)
                
            map[i][j] = mapIJ

            j = j + 2
            
        i = i + 1
    return map
            
            

# heightmap generation
# generation of the base
n = 16
base = [[scrand() for i in range(n)] for j in range(n)]

k = 1

# optional - representation via matplotlib
import matplotlib.pyplot as plt
#
while k < 6:
    base = mdp(base, n, 64/k)
    plt.imshow(base)
    plt.show()
    k = k + 1

for row in base:
    print row